﻿/// <reference path="..\TsLinq.d.ts" />
/// <reference path="..\StopWatch.ts" />
/// <reference path="..\Dictionary.ts" />

class PerformanceTesterBase implements ITester {

    _logger: ILogger;

    constructor(logger: ILogger) {
        this._logger = logger;    
    }

    runTest(): void {
        for (var prop in this) {
            if (typeof this[prop] == 'function' && prop != 'constructor' && prop != 'assert' && prop != 'expectError' && prop != 'init' && prop != 'runTest' && prop != 'measure' && prop != 'testPerformance') {
                var watch = StopWatch.start();
                this[prop]();
                var msTaken = watch.stop();
            }
        }
    }

    //
    //  Measures the time of the given call with the given message
    //
    measure(action: () => void): Timespan {
        var sw = StopWatch.start();
        action();
        return sw.stop(); 
    }

    //
    //  Tests the performance for the given libraries. 
    testPerformance(text: string,
        tsLinq: () => any,
        linqJs: () => any,
        prepareValue?: (value: any) => any) {
        var valueTsLinq: any, valueLinqJs: any;
        prepareValue = prepareValue || function (val: any) { return val; };
        var takenTsLinq = this.measure(() => valueTsLinq = prepareValue(tsLinq())).totalMilliseconds();
        var takenLinqJs = this.measure(() => valueLinqJs = prepareValue(linqJs())).totalMilliseconds();
        var spanStyleTsLinq = takenTsLinq < takenLinqJs || takenTsLinq == takenLinqJs ? 'font-weight: bold' : 'color: red';
        var spanStyleLinqJs = takenTsLinq > takenLinqJs || takenTsLinq == takenLinqJs ? 'font-weight: bold' : 'color: red';
        this._logger.debug([
            text, ', TsLinq: <span style="', spanStyleTsLinq, '">', takenTsLinq, 'ms</span> (value: ', valueTsLinq,
            '), Linq.js: <span style="', spanStyleLinqJs, '">', takenLinqJs, 'ms</span> (value: ' + valueLinqJs + ')'].join(''));
    }
} 